using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;
using HCP.Responses;
using HCP.SimpleJSON;
using UnityEngine;
using UnityEngine.UI;

namespace HCP.Requests
{
	public class PageSource : JobRequest
	{
		public PageSource(JSONClass json) : base(json)
		{
		}

		protected static string ConstructElementId(GameObject g)
		{
			Sticky component = g.GetComponent<Sticky>();
			if (component)
			{
				return component.Id;
			}
			return string.Empty;
		}

		protected static string FormatXMLNodeName(string name)
		{
			string pattern = "([\\(\\)\\s])";
			string replacement = ".";
			Regex regex = new Regex(pattern);
			return regex.Replace(name, replacement);
		}

		protected static void CompleteComponent(Component component, XmlDocument xmlDoc, XmlElement parentXmlElement)
		{
		}

		protected static void CompleteChild(GameObject gameObject, XmlDocument xmlDoc, XmlElement parentXmlElement, int index)
		{
			XmlElement parentXmlElement2 = parentXmlElement;
			IEnumerable<Behaviour> source = from c in gameObject.GetComponents<Behaviour>()
			where c != null
			select c;
			IEnumerable<Type> source2 = from c in source
			select c.GetType();
			Transform component = gameObject.GetComponent<Transform>();
			Func<Behaviour, bool> predicate = (Behaviour c) => c != null && (PageSource.s_namespaceInterests.Contains(c.GetType().Namespace) || PageSource.s_interestingTypes.Contains(c.GetType())) && !PageSource.s_uninterestingTypes.Contains(c.GetType());
			IEnumerable<Behaviour> source3 = source.Where(predicate);
			if (source3.Any<Behaviour>())
			{
				XmlElement xmlElement = xmlDoc.CreateElement(PageSource.FormatXMLNodeName(gameObject.name));
				xmlElement.SetAttribute("class", gameObject.GetType().FullName);
				xmlElement.SetAttribute("package", "UnityEngine.GameObject");
				xmlElement.SetAttribute("isHCP", "true");
				xmlElement.SetAttribute("name", gameObject.name);
				xmlElement.SetAttribute("xpath", Element.ConstructXPath(component));
				xmlElement.SetAttribute("index", index.ToString());
				xmlElement.SetAttribute("resource-id", PageSource.ConstructElementId(gameObject));
				xmlElement.SetAttribute("enabled", (!gameObject.activeSelf) ? "false" : "true");
				xmlElement.SetAttribute("displayed", (!gameObject.activeInHierarchy) ? "false" : "true");
				Rect rect = Element.ConstructScreenRect(component);
				xmlElement.SetAttribute("bounds", string.Format("[{0},{1}][{2},{3}]", new object[]
				{
					(int)rect.x,
					(int)rect.y,
					(int)rect.width,
					(int)rect.height
				}));
				xmlElement.SetAttribute("clickable", (!source2.Any((Type t) => PageSource.s_clickableTypes.Contains(t))) ? "false" : "true");
				xmlElement.SetAttribute("checkable", (!source2.Any((Type t) => PageSource.s_checkableTypes.Contains(t))) ? "false" : "true");
				parentXmlElement.AppendChild(xmlElement);
				parentXmlElement2 = xmlElement;
			}
			for (int i = 0; i < gameObject.transform.childCount; i++)
			{
				Transform child = gameObject.transform.GetChild(i);
				if (child.GetComponentsInChildren<Behaviour>().Where(predicate).Any<Behaviour>())
				{
					PageSource.CompleteChild(child.gameObject, xmlDoc, parentXmlElement2, i);
				}
			}
		}

		public override JobResponse Process()
		{
			XmlDocument xmlDocument = new XmlDocument();
			XmlElement xmlElement = xmlDocument.CreateElement("hierarchy");
			xmlDocument.AppendChild(xmlElement);
			GameObject[] array = (from g in UnityEngine.Object.FindObjectsOfType<GameObject>()
			where g.transform.parent == null
			select g).ToArray<GameObject>();
			for (int i = 0; i < array.Length; i++)
			{
				PageSource.CompleteChild(array[i].gameObject, xmlDocument, xmlElement, i);
			}
			JobResponse result;
			using (StringWriter stringWriter = new StringWriter())
			{
				using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter))
				{
					xmlDocument.WriteTo(xmlWriter);
					xmlWriter.Flush();
					result = new StringResponse(stringWriter.GetStringBuilder().ToString());
				}
			}
			return result;
		}

		protected static List<Type> s_uninterestingTypes = new List<Type>
		{
			typeof(Transform),
			typeof(RectTransform),
			typeof(Renderer)
		};

		protected static List<Type> s_interestingTypes = new List<Type>
		{
			typeof(Canvas),
			typeof(CanvasGroup)
		};

		protected static List<string> s_namespaceInterests = new List<string>
		{
			"UnityEngine.UI"
		};

		protected static List<Type> s_clickableTypes = new List<Type>
		{
			typeof(Button),
			typeof(InputField),
			typeof(Toggle)
		};

		protected static List<Type> s_checkableTypes = new List<Type>
		{
			typeof(Toggle)
		};
	}
}
